/**************************************************************************//**
 * @item     CosyOS-II Kernel
 * @file     sv_tick.c
 * @brief    滴答服务
 * @details  仅在 SysTick 中调用并执行，包括在滴答钩子、定时中断钩子、
             定时查询钩子、定时查询事件等处调用。
 * @author   迟凯峰
 * @version  V3.2.0
 * @date     2024.12.13
 ******************************************************************************/

#include "os_var.h"
#include "os_api.h"

/**
 @addtogroup CosyOS_内核服务
 @{
 *//**
 \defgroup   滴答服务
 \brief      仅在 SysTick 中调用并执行，包括在滴答钩子、定时中断钩子、
             定时查询钩子、定时查询事件等处调用。
 @{
 */

/**
 \brief      清除就绪延时
 \param      无
 \return     结果 [true：成功，false：失败]
 */
s_bool_t st_clear_delay(void) MCUCFG_C51USING
{
	if(s_sign_schedule_forbid){
		s_task_current->timer = 0;
		return true;
	}
	return false;
}

/**
 \brief      挂起任务
 \param[in]  htask     任务句柄
 \return     错误码 [0：无错误]
 */
s_ecode_t st_suspend_task(s_tasknode_tsp htask) MCUCFG_C51USING
{
	if(htask == OS_NULL){
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status < OS_STATUS_SUSPENDED){
		htask->status |= OS_STATUS_SUSPENDED;
		return OS_ECODE_NOERROR;
	}
	if(htask->status & OS_STATUS_SUSPENDED){
		return OS_ECODE_TASKSUSPENDED;
	}
	if(htask->status & OS_STATUS_STOPPED){
		return OS_ECODE_TASKSTOPPED;
	}
	if(htask->status == OS_STATUS_DELETED){
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		return OS_ECODE_DONOTKNOW;
	}
}

/**
 \brief      恢复任务
 \param[in]  htask     任务句柄
 \return     错误码 [0：无错误]
 */
s_ecode_t st_resume_task(s_tasknode_tsp htask) MCUCFG_C51USING
{
	if(htask == OS_NULL){
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status & OS_STATUS_SUSPENDED){
		htask->status &= (~OS_STATUS_SUSPENDED & 0xFF);
		return OS_ECODE_NOERROR;
	}
	if(htask->status < OS_STATUS_STOPPED){
		return OS_ECODE_TASKNOTSUSPENDED;
	}
	if(htask->status & OS_STATUS_STOPPED){
		return OS_ECODE_TASKSTOPPED;
	}
	if(htask->status == OS_STATUS_DELETED){
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		return OS_ECODE_DONOTKNOW;
	}
}

/**
 \brief      删除任务
 \param[in]  htask     任务句柄
 \return     错误码 [0：无错误]
 */
s_ecode_t st_delete_task(s_tasknode_tsp htask) MCUCFG_C51USING
{
	if(htask == OS_NULL){
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status < OS_STATUS_DELETED){
		htask->status = OS_STATUS_DELETED;
		return OS_ECODE_NOERROR;
	}
	if(htask->status == OS_STATUS_DELETED){
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		return OS_ECODE_DONOTKNOW;
	}
}

/**
 \brief      设置任务优先级
 \param[in]  htask     任务句柄
 \param[in]  pri       任务优先级
 \return     错误码 [0：无错误]
 */
s_ecode_t st_set_taskpri(s_tasknode_tsp htask, s_u8_t pri) MCUCFG_C51USING
{
	if(htask == OS_NULL){
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status < OS_STATUS_STOPPED){
		if(htask->pri != pri){
			htask->pri = pri;
			s_set_taskpri(htask);
			return OS_ECODE_NOERROR;
		}
		else{
			return OS_ECODE_TASKPRIUNCHANGED;
		}
	}
	if(htask->status & OS_STATUS_STOPPED){
		return OS_ECODE_TASKSTOPPED;
	}
	if(htask->status == OS_STATUS_DELETED){
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		return OS_ECODE_DONOTKNOW;
	}
}

/**
 \brief      设置阻塞（时间）
 \param[in]  htask     任务句柄
 \param[in]  tick      阻塞时间 [单位：滴答周期，0：等效于清除阻塞，~0：无限阻塞]
 \return     错误码 [0：无错误]
 */
s_ecode_t st_set_block(s_tasknode_tsp htask, s_delay_t tick) MCUCFG_C51USING
{
	if(htask == OS_NULL){
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){
		if(!tick){
			htask->status = OS_STATUS_READY;
		}
		htask->timer = tick;
		return OS_ECODE_NOERROR;
	}
	return OS_ECODE_TASKNOTBLOCKED;
}

/**
 \brief      清除阻塞（状态）
 \param[in]  htask     任务句柄
 \return     错误码 [0：无错误]
 */
s_ecode_t st_clear_block(s_tasknode_tsp htask) MCUCFG_C51USING
{
	if(htask == OS_NULL){
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){
		htask->status = OS_STATUS_READY;
		htask->timer = 0;
		return OS_ECODE_NOERROR;
	}
	return OS_ECODE_TASKNOTBLOCKED;
}

#if SYSCFG_BINARY == __ENABLED__
/**
 \brief      获取二值信号量
 \param[in]  hbin      二值信号量句柄
 \return     结果 [true：成功，false：失败]
 */
s_bool_t st_take_binary(s_binary_tsp hbin) MCUCFG_C51USING
{
	if(hbin->binary){
		hbin->binary = false;
		return true;
	}
	return false;
}
#endif

#if SYSCFG_SEMAPHORE == __ENABLED__
/**
 \brief      获取计数信号量
 \param[in]  hsem      计数信号量句柄
 \return     结果 [true：成功，false：失败]
 */
s_bool_t st_take_semaphore(s_semaph_tsp hsem) MCUCFG_C51USING
{
	if(hsem->counter){
		(hsem->counter)--;
		return true;
	}
	return false;
}

/**
 \brief      给予计数信号量
 \param[in]  hsem      计数信号量句柄
 \return     无
 */
void st_give_semaphore(s_semaph_tsp hsem) MCUCFG_C51USING
{
	if(hsem->counter < hsem->maximum){
		hsem->counter++;
	}
}
#endif

#if SYSCFG_FETION == __ENABLED__
/**
 \brief      接收飞信
 \param[in]  htbox     信箱句柄
 \return     飞信数据 [false：失败]
 */
m_fetion_t st_recv_fetion(s_tionbox_tsp htbox) MCUCFG_C51USING
{
	m_fetion_t fetion = htbox->fetion;
	htbox->fetion = false;
	return fetion;
}
#endif

#if SYSCFG_MAILBOX == __ENABLED__
/**
 \brief      接收邮件
 \param[in]  hmbox     邮箱句柄
 \return     邮件指针 [NULL：失败]
 */
void *st_recv_mail(s_mailbox_tsp hmbox) MCUCFG_C51USING
{
	if(hmbox->flag){
		hmbox->flag = false;
		return hmbox->mail;
	}
	return OS_NULL;
}

/**
 \brief      发送邮件
 \param[in]  hmbox     邮箱句柄
 \param[in]  mail      邮件指针
 \return     无
 */
void st_send_mail(s_mailbox_tsp hmbox, void *mail) MCUCFG_C51USING
{
	hmbox->flag = false;
	hmbox->mail = mail;
	hmbox->flag = true;
}
#endif

#if SYSCFG_MSGQUEUE == __ENABLED__
/**
 \brief      接收消息
 \param[in]  hque      队列句柄
 \return     消息指针 [NULL：失败]
 */
void *st_recv_msg(s_queue_tsp hque) MCUCFG_C51USING
{
	void *msg = OS_NULL;
	s_msgnode_tsp hmsg;
	hque->mutex = false;
	
	if(!hque->counter);
	else if(hque->type == __DYNAMIC__)
		sRecvMsg_Dynamic(msg);
	else
		sRecvMsg_Static(msg);
	
	hque->mutex = true;
	return msg;
}

/**
 \brief      发送消息
 \param[in]  hque      队列句柄
 \param[in]  msg       消息指针
 \return     错误码 [0：无错误]
 */
s_ecode_t st_send_msg(s_queue_tsp hque, void *msg) MCUCFG_C51USING
{
	hque->mutex = false;
	
	if(hque->counter == hque->len){
		#if SYSCFG_DEBUGGING == __ENABLED__
		s_alarm.overflow_msgqueue = true;
		#endif
		hque->mutex = true;
		return OS_ECODE_OVERFLOW_MSGQUEUE;
	}
	if(hque->type == __DYNAMIC__){
		s_msgnode_tsp hmsg = OS_NULL;
		hmsg = (s_msgnode_tsp)s_malloc(sizeof(s_msgnode_ts));
		if(hmsg == OS_NULL){
			#if SYSCFG_DEBUGGING == __ENABLED__
			s_fault.mallocfailed_msgnode = true;
			#endif
			hque->mutex = true;
			return OS_ECODE_MALLOCFAIL_MSGNODE;
		}
		sSendMsg_Dynamic(msg);
	}
	else
		sSendMsg_Static(msg);
	
	hque->mutex = true;
	return OS_ECODE_NOERROR;
}
#endif

/** @} */
/** @} */
